package com.javacv.plus.extensions.image.steps;

import com.javacv.plus.core.processor.ProcessorContext;
import com.javacv.plus.core.processor.ProcessorStep;
import com.javacv.plus.extensions.image.ImageProcessor;
import com.javacv.plus.extensions.image.ProcessorResult;
import com.javacv.plus.extensions.image.config.ImageConfig;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Point;
import org.bytedeco.opencv.opencv_core.Scalar;
import org.bytedeco.opencv.opencv_core.Size;
import org.bytedeco.opencv.global.opencv_imgproc;

/**
 * 文字水印步骤
 */
@Slf4j
public class TextWatermarkStep implements ProcessorStep<ImageProcessor, ProcessorResult> {
    private final String text;

    public TextWatermarkStep(String text) {
        this.text = text;
    }

    @Override
    public ProcessorResult execute(ImageProcessor processor, ProcessorContext context) throws Exception {
        Mat currentImage = context.getAttribute("currentImage");
        if (currentImage == null) {
            throw new IllegalStateException("当前图像为空");
        }

        if (text == null || text.trim().isEmpty()) {
            log.warn("水印文字为空，跳过文字水印步骤");
            return null;
        }

        log.debug("添加文字水印: {}", text);

        ImageConfig config = processor.getImageConfig();
        
        // 获取文字配置
        int fontSize = config.getFontSize();
        int[] textColor = config.getTextColor();
        ImageConfig.WatermarkPosition position = config.getWatermarkPosition();
        int margin = config.getWatermarkMargin();

        // 创建文字颜色（OpenCV使用BGR格式）
        Scalar color = new Scalar(textColor[2], textColor[1], textColor[0], 0);

        // 计算字体缩放比例（基于图像大小）
        double fontScale = Math.max(currentImage.rows(), currentImage.cols()) / 1000.0 * fontSize / 24.0;
        int thickness = Math.max(1, (int) (fontScale * 2));

        // 获取文字大小
        int[] baseLine = new int[1];
        Size textSize = opencv_imgproc.getTextSize(text, opencv_imgproc.FONT_HERSHEY_SIMPLEX, 
                fontScale, thickness, baseLine);

        // 计算文字位置
        Point textPosition = calculateTextPosition(currentImage, textSize, position, margin, baseLine[0]);

        // 添加文字（先加阴影效果）
        Point shadowPosition = new Point(textPosition.x() + 2, textPosition.y() + 2);
        Scalar shadowColor = new Scalar(0, 0, 0, 0); // 黑色阴影
        opencv_imgproc.putText(currentImage, text, shadowPosition, 
                opencv_imgproc.FONT_HERSHEY_SIMPLEX, fontScale, shadowColor, thickness, 
                opencv_imgproc.LINE_8, false);

        // 添加主文字
        opencv_imgproc.putText(currentImage, text, textPosition, 
                opencv_imgproc.FONT_HERSHEY_SIMPLEX, fontScale, color, thickness, 
                opencv_imgproc.LINE_8, false);

        context.setAttribute("currentImage", currentImage);
        context.setAttribute("processedImage", currentImage);

        log.debug("文字水印添加完成");
        return null;
    }

    /**
     * 计算文字位置
     */
    private Point calculateTextPosition(Mat image, Size textSize, 
            ImageConfig.WatermarkPosition position, int margin, int baseLine) {
        
        int imageWidth = image.cols();
        int imageHeight = image.rows();
        int textWidth = (int) textSize.width();
        int textHeight = (int) textSize.height();

        int x, y;

        switch (position) {
            case TOP_LEFT:
                x = margin;
                y = margin + textHeight;
                break;
            case TOP_RIGHT:
                x = imageWidth - textWidth - margin;
                y = margin + textHeight;
                break;
            case BOTTOM_LEFT:
                x = margin;
                y = imageHeight - margin - baseLine;
                break;
            case BOTTOM_RIGHT:
                x = imageWidth - textWidth - margin;
                y = imageHeight - margin - baseLine;
                break;
            case CENTER:
                x = (imageWidth - textWidth) / 2;
                y = (imageHeight + textHeight) / 2;
                break;
            default:
                x = imageWidth - textWidth - margin;
                y = imageHeight - margin - baseLine;
                break;
        }

        return new Point(x, y);
    }

    @Override
    public String getStepName() {
        return "TextWatermark";
    }

    @Override
    public int getPriority() {
        return 80;
    }
} 